package cn.tedu.mall.front.service.impl;

import cn.tedu.mall.common.exception.CoolSharkServiceException;
import cn.tedu.mall.common.restful.ResponseCode;
import cn.tedu.mall.front.service.IFrontCategoryService;
import cn.tedu.mall.pojo.front.entity.FrontCategoryEntity;
import cn.tedu.mall.pojo.front.vo.FrontCategoryTreeVO;
import cn.tedu.mall.pojo.product.vo.CategoryStandardVO;
import cn.tedu.mall.product.service.front.IForFrontCategoryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.management.remote.rmi._RMIConnection_Stub;
import javax.ws.rs.PUT;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author BJ
 * @date 2022/10/31 19:11
 */
@DubboService
@Service
@Slf4j
public class FrontCategoryServiceImpl implements IFrontCategoryService {

    @DubboReference
    private IForFrontCategoryService dubboCategoryService;

    @Autowired
    private RedisTemplate redisTemplate;
    public static final String CATEGORY_TREE_KEY = "category_tree";

    // 构建三级分类树（前台页面展示）
    @Override
    public FrontCategoryTreeVO categoryTree() {
        // 先判断redis中是否存在三级分类树
        if (redisTemplate.hasKey(CATEGORY_TREE_KEY)) {
            //将三级分类树添加到redis中
            FrontCategoryTreeVO<FrontCategoryEntity> treeVO = (FrontCategoryTreeVO<FrontCategoryEntity>) redisTemplate.boundValueOps(CATEGORY_TREE_KEY).get();
            return treeVO;
        }
        //不存在三级分类树，则根据分类构建三级分类树
        List<CategoryStandardVO> categoryStandardVOS = dubboCategoryService.getCategoryList();
        FrontCategoryTreeVO<FrontCategoryEntity> treeVO = innitTree(categoryStandardVOS);
        redisTemplate.boundValueOps(CATEGORY_TREE_KEY).set(treeVO, 1, TimeUnit.MINUTES);

        return treeVO;
    }

    private FrontCategoryTreeVO<FrontCategoryEntity> innitTree(List<CategoryStandardVO> categoryStandardVOS) {
        // 第一步：创建一个map，key存放父级id，value存放子级数据
        Map<Long, List<FrontCategoryEntity>> map = new HashMap<>();
        for (CategoryStandardVO categoryStandardVO : categoryStandardVOS) {
            FrontCategoryEntity frontCategoryEntity = new FrontCategoryEntity();
            BeanUtils.copyProperties(categoryStandardVO, frontCategoryEntity);
            Long parentId = frontCategoryEntity.getParentId();
            if (!map.containsKey(parentId)) {
                List<FrontCategoryEntity> value = new ArrayList<>();
                value.add(frontCategoryEntity);
                map.put(parentId, value);
            } else {
                map.get(parentId).add(frontCategoryEntity);
            }
        }
        // 设置一级父类父id为0
        List<FrontCategoryEntity> firstLevels = map.get(0L);
        if (firstLevels == null || firstLevels.isEmpty()) {
            throw new CoolSharkServiceException(ResponseCode.NOT_FOUND, "一级分类树不存在！");
        }
        for (FrontCategoryEntity firstLevel : firstLevels) {
            // 根据一级树id得到二级树父id
            Long secondParentId = firstLevel.getId();
            List<FrontCategoryEntity> secondLevels = map.get(secondParentId);
            if (secondLevels == null || secondLevels.isEmpty()) {
                log.warn("当前二级分类对象没有三级级分类内容");
                continue;

            }
            for (FrontCategoryEntity secondLevel : secondLevels) {
                Long thirdParentId = secondLevel.getId();
                List<FrontCategoryEntity> thirdLevels = map.get(thirdParentId);
                if (thirdLevels == null || thirdLevels.isEmpty()) {
                    log.warn("当前级分类对象没有三级级分类内容");
                    continue;
                }
                // 将三级分类对象集合添加到 当前二级分类对象的 childrens属性中
                secondLevel.setChildrens(thirdLevels);
            }
            firstLevel.setChildrens(secondLevels);
        }
        FrontCategoryTreeVO<FrontCategoryEntity> treeVO = new FrontCategoryTreeVO<>();
        treeVO.setCategories(firstLevels);
        return treeVO;
    }
}
